package mysql

import (
	"context"
	"go.uber.org/zap"
	"gorm.io/gorm"
	log "maya-service/collector/logger"
	"maya-service/config"
	"maya-service/model"
	"maya-service/model/entity"
)

var SysUsers = &sysUsers{}

type sysUsers struct{}

func init() {
	Register(SysUsers)
}

func (a *sysUsers) Init() {
	if config.Conf.AutoMigrate {
		p := &entity.SysUsers{}
		if db.Migrator().HasTable(p) {
			log.Debug("table already exist: ", zap.String("table", p.TableName()))
			return
		}
		if err := db.AutoMigrate(p); err != nil {
			log.Error("filed to create table please check config or manually create", zap.String("table", p.TableName()), zap.String("err", err.Error()))
		} else {
			log.Info("create table successfully", zap.String("table", p.TableName()))
		}
	}
}

// Create
func (a *sysUsers) Create(ctx context.Context, m *entity.SysUsers) (int64, error) {
	err := GetDB(ctx).Create(m).Error
	return m.Id, err
}

// Find detail
func (a *sysUsers) Find(ctx context.Context, in *model.SysUsersInfoRequest) (*entity.SysUsers, error) {
	e := &entity.SysUsers{}

	q := GetDB(ctx).Model(&entity.SysUsers{})

	count := 0
	if in.Id > 0 {
		q = q.Where("id = ?", in.Id)
		count++
	}

	if in.UserName != "" {
		q = q.Where("username = ?", in.UserName)
		count++
	}

	if in.UserId != "" {
		q = q.Where("Uuid = ?", in.UserId)
		count++
	}

	if count == 0 {
		return e, nil
	}

	err := q.First(&e).Error
	return e, err
}

// Update
func (a *sysUsers) Update(ctx context.Context, id int64, dict map[string]interface{}) error {
	return GetDB(ctx).Model(&entity.SysUsers{}).Where("id = ?", id).Updates(dict).Error
}

// Delete
func (a *sysUsers) Delete(ctx context.Context, id int64) error {
	return GetDB(ctx).Delete(&entity.SysUsers{}, id).Error
}

// List query list
func (a *sysUsers) List(ctx context.Context, in *model.SysUsersListRequest) (int, []*entity.SysUsers, error) {
	var (
		q         = GetDB(ctx).Model(&entity.SysUsers{})
		err       error
		total     int64
		sysUserss []*entity.SysUsers
	)

	if in.Uuid != nil {

		q = q.Where("uuid like ?", in.Uuid)

	}

	if in.Username != nil {

		q = q.Where("username like ?", in.Username)

	}

	if in.Password != nil {

		q = q.Where("password like ?", in.Password)

	}

	if in.NickName != nil {

		q = q.Where("nick_name like ?", in.NickName)

	}

	if in.SideMode != nil {

		q = q.Where("side_mode like ?", in.SideMode)

	}

	if in.HeaderImg != nil {

		q = q.Where("header_img like ?", in.HeaderImg)

	}

	if in.BaseColor != nil {

		q = q.Where("base_color like ?", in.BaseColor)

	}

	if in.ActiveColor != nil {

		q = q.Where("active_color like ?", in.ActiveColor)

	}

	if in.AuthorityId != nil {

		q = q.Where("authority_id = ?", in.AuthorityId)

	}

	if in.Phone != nil {

		q = q.Where("phone like ?", in.Phone)

	}

	if in.Email != nil {

		q = q.Where("email like ?", in.Email)

	}

	if in.Enable != nil {

		q = q.Where("enable like ?", in.Enable)

	}

	if in.CreatedAt != nil {

		q = q.Where("created_at = ?", in.CreatedAt)

	}

	if in.UpdatedAt != nil {

		q = q.Where("updated_at = ?", in.UpdatedAt)

	}

	if in.DeletedAt != nil {

		q = q.Where("deleted_at = ?", in.DeletedAt)

	}

	if err = q.Count(&total).Error; err != nil {
		return 0, nil, err
	}
	if err = q.Limit(in.Size).Offset((in.Index - 1) * in.Size).Find(&sysUserss).Error; err != nil {
		return 0, nil, err
	}
	return int(total), sysUserss, nil
}

// ExecTransaction execute database transaction
func (a *sysUsers) ExecTransaction(ctx context.Context, callback func(ctx context.Context) error) error {
	return GetDB(ctx).Transaction(func(tx *gorm.DB) error {
		ctx = context.WithValue(ctx, ContextTxKey, tx)
		return callback(ctx)
	})
}
